/*
 *  lwbImage.cpp
 *  Yellowtail
 *
 *  Created by Lee Byron on 8/31/08.
 *  Copyright 2008 __MyCompanyName__. All rights reserved.
 *
 */

#include "mfTexture.h"

// set verticies
const GLshort spriteVertices[8] = {0,0, 1,0, 0,1, 1,1};

mfTexture::mfTexture()
{
	// this is never being called... probably because it's obj-c++
	width = 0;
	height = 0;
	textureID = 0;
}

mfTexture::~mfTexture()
{
	// this is never being called... probably because it's obj-c++
	clear();
}

void mfTexture::loadImage(string filename)
{
	//loadImage(filename, OF_IMAGE_COLOR);
	loadImage(filename, OF_IMAGE_COLOR_ALPHA);
}

void mfTexture::loadImage(string filename, int _type)
{
	// load image texture
	CGImageRef spriteImage;
	CGContextRef spriteContext;
	GLubyte *spriteData;
	
	spriteImage = [UIImage imageNamed:[NSString stringWithCString:filename.c_str()]].CGImage;
	
	// Get the width and height of the image
	width = (int) CGImageGetWidth(spriteImage);
	height = (int) CGImageGetHeight(spriteImage);
	
	// Texture dimensions must be a power of 2.
	tex_w = ofNextPow2(width);
	tex_h = ofNextPow2(height);
	
	// And because of that, we have to set our t/u coordinates to fit
	tex_t = (float)(width) / (float)tex_w;
	tex_u = (float)(height) / (float)tex_h;
	
	spriteTexCoords[0] = 0;
	spriteTexCoords[1] = 0;
	spriteTexCoords[2] = tex_t;
	spriteTexCoords[3] = 0;
	spriteTexCoords[4] = 0;
	spriteTexCoords[5] = tex_u;
	spriteTexCoords[6] = tex_t;
	spriteTexCoords[7] = tex_u;
	
	type = _type;
	switch (_type){
		case OF_IMAGE_GRAYSCALE:
			bpp = 1;
			glType = GL_LUMINANCE;
			texType = GL_LUMINANCE;
			break;
		case OF_IMAGE_COLOR_ALPHA:
			bpp = 4;
			glType = GL_RGBA;
			texType = GL_RGBA;
			break;
		case OF_IMAGE_COLOR:
		default:
			bpp = 3;
			glType = GL_RGB;
			texType = GL_RGB;
			break;
	}
	
	if(spriteImage) {		
		// Allocated memory needed for the bitmap context
		spriteData = (GLubyte *) malloc(tex_w * tex_h * bpp);
		spriteContext = CGBitmapContextCreate(spriteData, tex_w, tex_h, 8, tex_w * bpp, CGImageGetColorSpace(spriteImage), type==OF_IMAGE_COLOR_ALPHA?kCGImageAlphaPremultipliedLast:kCGImageAlphaNone);

		CGContextClearRect(spriteContext, CGRectMake(0.0, 0.0, tex_w, tex_h));
		CGContextTranslateCTM(spriteContext, 0, tex_h - height);
		//CGContextDrawImage(spriteContext, CGRectMake(0.0, (CGFloat)(tex_h-height), (CGFloat)width, (CGFloat)height), spriteImage);
		
		
		CGContextDrawImage(spriteContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), spriteImage);

		
		// You don't need the context at this point, so you need to release it to avoid memory leaks.
		CGContextRelease(spriteContext);
		CGImageRelease(spriteImage);
		
		// Use OpenGL ES to generate a name for the texture.
		glGenTextures(1, &textureID);
		// Bind the texture name. 
		glBindTexture(GL_TEXTURE_2D, textureID);
		// Specify a 2D texture image, providing a pointer to the image data in memory
		glTexImage2D(GL_TEXTURE_2D, 0, texType, tex_w, tex_h, 0, glType, GL_UNSIGNED_BYTE, spriteData);
		// Release the image data
		free(spriteData);
		
		// Set the texture parameters to use a minifying filter and a linear filer (weighted average)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	}
}

void mfTexture::draw(float x, float y)
{
	draw(x,y,width,height);
}

void mfTexture::draw(float x, float y, float w, float h)
{
	glPushMatrix();
	if( cornerMode == OF_RECTMODE_CENTER ){
		glTranslatef(x - w*0.5f, y - h*0.5f, 0);
	}else{
		glTranslatef(x, y, 0);
	}
	glScalef(w, h, 1);
	
	glVertexPointer(2, GL_SHORT, 0, spriteVertices);
	glEnableClientState(GL_VERTEX_ARRAY);
	glTexCoordPointer(2, GL_FLOAT, 0, spriteTexCoords);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	
	glBindTexture(GL_TEXTURE_2D, textureID);
	glEnable(GL_TEXTURE_2D);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	glDisable(GL_TEXTURE_2D);
	
	glPopMatrix();
}

void mfTexture::clear()
{
	width = 0;
	height = 0;
	if(textureID!=0){
		glDeleteTextures(1, &textureID);
	}
	textureID=0;
}